<template>
  <div class="form">
    <a-row class="form-item">
      <a-col span="8">主标题名称</a-col>
      <a-col span="16">
        <a-input
          v-model="formData.mainTitle"
          @keyup.enter="updateMainTitle"
          @blur="updateMainTitle"
        />
      </a-col>
    </a-row>
    <div
      v-for="(tab, index) in formData.tabs"
      :key="index"
      class="tabItem"
      :class="{ active: isActiveTab(tab.id) }"
      @drop.stop="drop(index)"
      @dragover="dragover"
      @dragstart="dragstart(index)"
    >
      <a-row class="tabRow">
        <a-col
          span="8"
          class="subTabTitle"
          draggable="true"
          @click.stop="click(tab.id)"
          >Tab {{ index + 1 }}</a-col
        >
        <a-col span="16">
          <a-tooltip title="复制页面">
            <a-icon-font
              class="icon"
              type="iconfuzhihuaban"
              @click="copyTab(tab, index)"
            ></a-icon-font>
          </a-tooltip>
          <a-tooltip title="删除页面">
            <a-icon-font
              class="icon"
              type="iconicon-beifen5"
              @click="deleteTab(tab, index)"
            ></a-icon-font>
          </a-tooltip>
        </a-col>
      </a-row>
      <a-row class="tabRow">
        <a-col span="8" draggable="true" @click.stop="click(tab.id)"
          >页面标题</a-col
        >
        <a-col span="16">
          <a-input
            v-model="tab.title"
            @blur="updateSubTitle"
            @keyup.enter="updateSubTitle"
          />
        </a-col>
      </a-row>
    </div>
    <div class="createTab" @click="createTab">新增子页面</div>
  </div>
</template>

<script lang="ts">
import { Vue, Prop, Component } from 'vue-property-decorator'
import { IKeyValue } from './interface'
import VisualizationStore from '@/store/modules/visualization'
import { saveWidgetBatch, deleteWidgetBatch } from '@/api/widget'
import { buildSaveParameters } from '@/util/common'
import { cloneDeep } from 'lodash'

@Component({})
export default class VistabsForm extends Vue {
  @Prop() formData!: IKeyValue

  private dragTabIndex = -1

  get projectId() {
    return (this.$route.params as any).id || localStorage.getItem('projectId')
  }

  get dashBoardId() {
    return VisualizationStore.currentDashboard.id
  }

  private isActiveTab(tabId: string) {
    return (
      VisualizationStore.currentGridItem?.chartOptions.activeTabId === tabId
    )
  }

  private click(tabId: string) {
    if (this.formData.activeTabId !== tabId) {
      this.formData.activeTabId = tabId
      this.$emit('change', 'activeTabId', this.formData.activeTabId)
    }
  }

  private getGridSubItemsByParentId(parentId: string) {
    return VisualizationStore.gridList.filter(
      (gridItem) => gridItem.chartOptions.parentId === parentId
    )
  }

  private dragstart(tabIndex: number) {
    console.log('drag tab index:', tabIndex)
    this.dragTabIndex = tabIndex
  }

  private dragover(event: MouseEvent) {
    event.preventDefault()
  }

  private drop(dropTabIndex: number) {
    console.log(dropTabIndex)
    if (this.dragTabIndex === dropTabIndex) {
      return
    }

    const dragTab = this.formData.tabs[this.dragTabIndex]
    if (this.dragTabIndex > dropTabIndex) {
      this.formData.tabs.splice(this.dragTabIndex, 1)
      this.formData.tabs.splice(dropTabIndex, 0, dragTab)
    } else if (this.dragTabIndex < dropTabIndex) {
      this.formData.tabs.splice(dropTabIndex + 1, 0, dragTab)
      this.formData.tabs.splice(this.dragTabIndex, 1)
    }

    this.dragTabIndex = -1
    this.$emit('change', 'tabs', this.formData.tabs)
  }

  private updateMainTitle() {
    const fieldValue = this.formData.mainTitle
    const fieldName = 'mainTitle'
    this.$emit('change', fieldName, fieldValue)
  }

  private updateSubTitle() {
    const fieldValue = this.formData.tabs
    const fieldName = 'subTitle'
    this.$emit('change', fieldName, fieldValue)
  }

  private createTab() {
    const fieldName = 'tabs'
    const { tabs } = this.formData
    const tabId = `vistabs-tab-${Math.random().toString(36).slice(-8)}`
    tabs.push({
      id: tabId,
      title: `页面${tabs.length + 1}`,
    })
    this.formData.activeTabId = tabId
    this.$emit('change', fieldName, tabs)
  }

  private deleteTab(tab: any, index: number) {
    if (this.formData.tabs.length <= 1) {
      this.$message.info('只有一个tab时不能删除')
      return
    }

    const tabItems = this.getGridSubItemsByParentId(tab.id)
    if (tabItems.length <= 0) {
      const fieldName = 'tabs'
      this.formData.tabs.splice(index, 1)
      this.$emit('change', fieldName, this.formData.tabs)
    } else {
      this.$confirm({
        content: '该页面含有图表或控件内容，是否确认删除？',
        onOk: () => {
          this.confirmDelete(index)
        },
      })
    }
  }

  private confirmDelete(deleteTabIndex: number) {
    const widgetIds: any = []
    const deleteTabId = this.formData.tabs[deleteTabIndex].id
    const { gridList } = VisualizationStore
    const tabItems = this.getGridSubItemsByParentId(deleteTabId).map(
      (item) => item.i
    )

    for (let i = gridList.length - 1; i >= 0; i -= 1) {
      const gridItem = gridList[i]
      if (tabItems?.includes(gridItem.i.toString()) && gridItem.widgetId) {
        // 获取要删除的item.widgetId
        widgetIds.push(gridItem.widgetId)
        // 删除元素
        VisualizationStore.removeGridItem(i, 1)
      }
    }

    this.formData.tabs.splice(deleteTabIndex, 1)
    deleteWidgetBatch({
      data: {
        projectId: this.projectId,
        widgetIds,
      },
    }).then(() => {
      // 如果当前删除的Tab是激活状态
      if (deleteTabId === this.formData.activeTabId) {
        const nextActiveTabIndex: number =
          deleteTabIndex < 1 ? deleteTabIndex : deleteTabIndex - 1
        this.formData.activeTabId = this.formData.tabs[nextActiveTabIndex].id
      }

      this.$emit('change', 'tabs', this.formData.tabs)
    })
  }

  private async copyTab(tab: any, index: number) {
    // 创建tab，并保存tab信息
    const { tabs } = this.formData
    const tabId = `vistabs-tab-${Math.random().toString(36).slice(-8)}`
    this.formData.activeTabId = tabId
    tabs.splice(index + 1, 0, {
      id: tabId,
      title: `${tab.title}（复制）`,
    })

    // 整理要复制的item数据，提交后端获取widgetId
    const tabItemIds = this.getGridSubItemsByParentId(tab.id).map(
      (item) => item.i
    )
    const items: any = []
    const widgets: any = []
    const oldWidgetIds: any = [] // 保存旧的widgetId，便于后续与新的widgetId对应上

    VisualizationStore.gridList.forEach((gridItem) => {
      if (tabItemIds?.includes(gridItem.i.toString())) {
        oldWidgetIds.push(gridItem.widgetId)
        const copyItem = cloneDeep(gridItem)
        const item = {
          ...copyItem,
          chartOptions: {
            ...copyItem.chartOptions,
            parentId: tabId,
            title: `${copyItem.chartOptions.title}（复制）`,
          },
          i: this.generateItemId(copyItem.chartType),
          widgetId: '',
        }
        items.push(item)
        const parameter = buildSaveParameters(item)
        parameter.data.dashBoardId = this.dashBoardId
        widgets.push(parameter.data)
      }
    })

    const response = await saveWidgetBatch({
      data: {
        projectId: this.projectId,
        widgets,
      },
    })
    const newWidgetIds = response.data.result

    // 更新widgetId信息，并更新数据到store(gridList)中
    items.forEach((item: any, itemIndex: number) => {
      // 更新widgetId
      item.widgetId = newWidgetIds[itemIndex]

      // 针对筛选器的关联图表处理：如果该item有关联图表，将旧的widgetId替换为新的widgetId
      if (item.chartOptions.associationChart) {
        const { associationChart } = item.chartOptions
        associationChart.forEach((widgetId: number, chartIndex: number) => {
          const oldWidgetIdIndex = oldWidgetIds.findIndex(
            (oldWidgetId: number) => oldWidgetId === widgetId
          )
          associationChart[chartIndex] = newWidgetIds[oldWidgetIdIndex]
        })
      }

      // 针对通过pipeline创建的图表关联关系处理：
      if (item.interactionJson && item.interactionJson.relateWidgets) {
        const { relateWidgets } = item.interactionJson
        relateWidgets.forEach((relateWidget: any, widgetIndex: number) => {
          const oldWidgetIdIndex = oldWidgetIds.findIndex(
            (oldWidgetId: number) => oldWidgetId === relateWidget.widgetId
          )
          relateWidgets[widgetIndex].widgetId = newWidgetIds[oldWidgetIdIndex]
        })
      }

      // 将新创建的gridItem添加到gridList中
      VisualizationStore.addGridItem(item)
    })

    this.$emit('change', 'tabs', tabs)
  }

  private generateItemId(chartType: string | string[]) {
    const prefix = Array.isArray(chartType) ? chartType[0] : chartType
    return `${prefix}${Math.random().toString(36).slice(-8)}`
  }
}
</script>

<style lang="less" scoped>
.form {
  /deep/ .ant-select {
    width: 100%;
  }

  .form-item {
    line-height: 40px;
  }
}

.panel-title {
  font-weight: bolder;
  height: 40px;
  line-height: 40px;
  margin-top: 4px;
  position: relative;
  width: 100%;

  .anticon {
    font-size: 8px;
    font-weight: normal;
    height: 40px;
    line-height: 40px;
    position: absolute;
    right: 10px;
  }

  .panel-title-hr {
    background-color: #e9e9e9;
    height: 1px;
    left: -16px;
    position: absolute;
    right: -20px;
  }
}

.tabItem {
  border-left: 2px solid #ccc;
  margin: 5px 0;
  padding-left: 10px;

  &.active {
    border-left-color: #5561ff;
  }
}

.tabRow {
  line-height: 25px;

  .icon {
    cursor: pointer;
    margin-right: 10px;
  }
}

.subTabTitle {
  cursor: move;
}

.createTab {
  color: #5561ff;
  cursor: pointer;
  padding-top: 10px;
}
</style>
